﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Luna
{
	public interface IServiceProvider
	{
        /// <summary>
        /// Register a service instance to the service registry.
        /// </summary>
        /// <param name="serviceInstance"></param>
        /// <returns></returns>
        object addService(object serviceInstance);

        /// <summary>
        /// Retrieve the first service instance that supports the required contract.
        /// </summary>
        /// <typeparam name="ServiceContract">A class or interface represents the contract for which the service should support.</typeparam>
        /// <returns></returns>
		ServiceContract getService<ServiceContract>() where ServiceContract : class;

        /// <summary>
        /// Retrive the first service instance that supports the required contract and meets custom constraints.
        /// The constraint is defined in a typed predicate parameter.
        /// </summary>
        /// <typeparam name="ServiceContract">A class or interface represents the contract for which the service should support.</typeparam>
        /// <param name="pred">The custom typed predicate determines whether found service is met user constraints.</param>
        /// <returns></returns>
		ServiceContract getService<ServiceContract>(Predicate<ServiceContract> pred) where ServiceContract : class;

        /// <summary>
        /// Retrieve all service instances that support the required contract.
        /// </summary>
        /// <typeparam name="ServiceContract">A class or interface represents the contract for which the service should support.</typeparam>
        /// <returns></returns>
		IEnumerable<ServiceContract> findServices<ServiceContract>() where ServiceContract : class;

		/// <summary>
		/// Retrieve all service instances that support the required contract and meet custom constraints.
		/// </summary>
		/// <typeparam name="ServiceContract">A class or interface represents the contract for which the service should support.</typeparam>
		/// /// <param name="pred">The custom typed predicate determines whether found service is met user constraints.</param>
		/// <returns></returns>
		IEnumerable<ServiceContract> findServices<ServiceContract>(Predicate<ServiceContract> pred) where ServiceContract : class;

        /// <summary>
        /// Unregister a service instance from current service registry.
        /// </summary>
        /// <param name="serviceInstance"></param>
		void removeService(object serviceInstance);

        /// <summary>
        /// Unregister all service instances that meet custom constraints from current service.
        /// </summary>
        /// <typeparam name="ServiceContract">>A class or interface represents the contract for which the service should support.</typeparam>
        /// <param name="pred">The custom typed predicate determines whether found service is met user constraints.</param>
		void removeServices<ServiceContract>(Predicate<ServiceContract> pred);
	}
}
